Skip to content

Add opt-in CJK text rendering support to Mod.dll#35

Open
sharrrkcat wants to merge 3 commits into
SWRC-Modding:masterfrom
sharrrkcat:cjk-text
Open

Add opt-in CJK text rendering support to Mod.dll#35
sharrrkcat wants to merge 3 commits into
SWRC-Modding:masterfrom
sharrrkcat:cjk-text

Conversation

@sharrrkcat

Copy link
Copy Markdown

The retail Engine.dll is an ANSI build: the canvas text functions walk strings byte by byte, so font CharRemap keys above 0xFF can never be produced and double-byte (GBK / Shift-JIS) text renders as blanks. The official Japanese release solved this by shipping a modified Engine.dll.

This instead detours four Engine exports from Mod.dll with DBCS-aware reimplementations — UCanvas::WrappedPrint, UCanvas::ClippedPrint UCanvas::ClippedStrLen and FCanvasUtil::DrawString — pairing lead+trail bytes into 16-bit CharRemap keys, the same scheme the JP release used. Struct layouts follow the Engine.dll decompilation (reference offsets noted in comments), and exports are resolved by name rather than hardcoded addresses.

Off by default: the hooks are only installed when EnableCJKText=True is set under [Mod.SWRCFix] in System.ini, so existing installs are unaffected (unconditional pairing could mis-pair extended-Latin bytes in EFIGS text).

Tested on the Steam build with a Simplified Chinese font and localization: menus, title cards, loading screens, hints, briefing and in-game subtitles all render correctly; single-byte text is unchanged with the flag on or off.

The retail Engine.dll is an ANSI build: text drawing iterates strings
byte by byte, so CharRemap keys above 0xFF can never be produced and
DBCS text renders as blanks. This detours UCanvas::WrappedPrint,
UCanvas::ClippedPrint (the menu text path), UCanvas::ClippedStrLen and
FCanvasUtil::DrawString with reimplementations that pair GBK/Shift-JIS
lead+trail bytes into 16-bit CharRemap keys - the same scheme the
official Japanese release used with its modified Engine.dll.

The hooks are only installed when the new EnableCJKText config
property on SWRCFix is set (System.ini [Mod.SWRCFix], default off), so
existing installs are unaffected: DBCS pairing could otherwise mis-pair
extended-Latin bytes in the EFIGS localizations (e.g. 0xFC followed by
a trail-range byte).
@ffsPLASMA

Copy link
Copy Markdown

Hello there,

Thanks for the pull request.
Did you use Visual Studio 2003 or a later version?
Because Im getting this error when compiling on VS 2003:

\Mod\Src\CJKText.cpp(51): error C4234: nonstandard extension used : '__thiscall' keyword reserved for future use
\Mod\Src\CJKText.cpp(266): error C4234: nonstandard extension used : '__thiscall' keyword reserved for future use

@sharrrkcat

Copy link
Copy Markdown
Author

Hi,

Thanks for testing with VS2003. I pushed a compatibility fix.

I originally built and tested this with VS2022. I’ve now removed the explicit __thiscall function pointer typedefs and replaced them with VS2003-friendly call patterns. I also cleaned non-ASCII comment punctuation and trailing whitespace.

I re-tested the converted VS2022 project successfully, but I don’t have a VS2003 environment locally, so please re-run the VS2003 build when convenient.

@ffsPLASMA

Copy link
Copy Markdown

Now it compiles fine.
I tried it with Japanese and Thai translation files and OrbitFont.utx, yet it fails to display the characters ingame.
Am I missing something? Do I have to set my system language/localization to that language as well? Or are the OrbitFont.utx files not compatible?
Could you please check with those language options as well upload your chinese font file?

https://dl.swrc-modding.net/apps/files/files/425?dir=/SWRC/Translations

@sharrrkcat

Copy link
Copy Markdown
Author

Based on the current commit, three things are required for the font to work:

  1. A matching OrbitFonts.utx file.
  2. Enable the hook in System.ini:

[Mod.SWRCFix]
EnableCJKText=True

  1. The localized text files, e.g. *.jpt / *.cht, must be saved in the matching legacy DBCS encoding, not UTF-8.
    For Japanese this means Shift-JIS, and for Simplified Chinese this means GBK.

You should not need to change the Windows system language/locale. The important part is the file encoding. The current hook does not decode UTF-8/Unicode; it only pairs DBCS lead/trail bytes into the 16-bit CharRemap key used by the font, so UTF-8 byte sequences will not match the font remap table.

9425b837-ebf6-4ce7-851e-1e89dcc2f57b

Thai is not supported by this hook. This approach is only suitable for CJK-related DBCS encodings/languages.

Also, one thing I realized: my encoding analysis was based on an official Japanese language pack that directly replaces the *.int files, so I missed the existing [Engine.Engine] Language=... mechanism for loading language-specific extensions. That is why I added the explicit EnableCJKText option, but this requires rebuilding Mod.u, which is not ideal.

Do you think it would be better to change the hook so it automatically enables itself when Language is set to a CJK extension such as cht or jpt?

The Chinese font file is quite large because of the number of Chinese glyphs. I will optimize it first and upload it soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants